from datetime import datetime, timedelta, timezone
from types import UnionType

from fastapi import HTTPException, status, Depends
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from jose import JWTError, jwt

# to get a string like this run:
# openssl rand -hex 32
__SECRET_KEY = "a15e080ce3ead4562605ee88a7b794fe0a6bbd6771241a9e101b72db063b0af8"
__ALGORITHM = "HS256"
__ACCESS_TOKEN_EXPIRE_MINUTES = 30


oauth2_scheme = OAuth2PasswordBearer(tokenUrl="user/login")


def create_token(
        data: dict,
        expires_delta: timedelta | None = None
    ) -> str:
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.now(timezone.utc) + expires_delta
    else:
        # 如果没有传入时间差值，则默认按照15分钟计算
        expire = datetime.now(timezone.utc) + timedelta(minutes=15)
    print(expire)
    to_encode.update({"expires": expire.__str__()})
    encoded_jwt = jwt_encode(to_encode)
    return encoded_jwt


async def decode_token(token: str = Depends(oauth2_scheme)) -> dict:
    user_dict = jwt_decode(token=token)
    return user_dict


def jwt_encode(to_encode: dict) -> str:
    return jwt.encode(to_encode, __SECRET_KEY, algorithm=__ALGORITHM)


def jwt_decode(token: str) -> dict:
    print(token)
    try:
        payload = jwt.decode(token, __SECRET_KEY, algorithms=[__ALGORITHM])
        return payload
    except JWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Could not validate credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )

